package com.hmall.item.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.hmall.common.dto.FiltersDTO;
import com.hmall.common.dto.PageDTO;
import com.hmall.item.dto.ItemDTO;
import com.hmall.item.mapper.ItemMapper;
import com.hmall.item.pojo.FiltersVO;
import com.hmall.item.pojo.Item;
import com.hmall.item.pojo.ItemDoc;
import com.hmall.item.service.IItemService;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
public class ItemService extends ServiceImpl<ItemMapper, Item> implements IItemService {

    @Autowired
    private ItemMapper itemMapper;
    @Override
    public PageDTO listPage(Integer page, Integer size) {

        PageHelper.startPage(page,size);
        Page list =itemMapper.pagelist();
//        PageDTO.builder().list(Collections.singletonList(s.getRecords()))
//                .total(itemPage.getTotal());
        PageDTO pageDTO = new PageDTO();
            pageDTO.setList(list.getResult());
            pageDTO.setTotal(list.getTotal());

//        Page<Item> page1 = new Page<>(page,size);
//        itemMapper.selectPage(page1,null);
//
//
//        PageDTO pageDTO = new PageDTO();
//        pageDTO.setTotal(page1.getTotal());
//        pageDTO.setList(page1.getRecords());
        return pageDTO;

    }

    @Override
    public Item getItemById(Long id) {
        Item item = itemMapper.selectById(id);

        return item;
    }

    @Override
    public void insert(ItemDTO itemDTO) {
        Item item = BeanUtil.copyProperties(itemDTO, Item.class);
        Date date = new Date();
        item.setCreateTime(date);
        item.setUpdateTime(date);
        itemMapper.insert(item);
    }

    @Override
    public void insertItem(ItemDTO itemDTO) {
        Item item = BeanUtil.copyProperties(itemDTO, Item.class);
        Date date = new Date();
        item.setUpdateTime(date);
        itemMapper.insert(item);
    }

    @Override
    public FiltersVO selrct(String category) {
       List<String> brand =itemMapper.selectBrand(category);
        FiltersVO filtersVO = FiltersVO.builder().brand(brand).build();
        return filtersVO;

    }

     @Autowired
    private RestHighLevelClient client;
    @Override
    public PageDTO<Item> pagelist(FiltersDTO filtersDTO) {
//        LambdaQueryWrapper<Item> wrapper = new LambdaQueryWrapper<>();
//         wrapper.like(StringUtils.isNotBlank(filtersDTO.getKey()), Item::getName, filtersDTO.getKey())
//                .eq(StringUtils.isNotBlank(filtersDTO.getCategory()), Item::getCategory, filtersDTO.getCategory())
//                .eq(StringUtils.isNotBlank(filtersDTO.getBrand()), Item::getBrand, filtersDTO.getBrand())
//                .ge(filtersDTO.getMinPrice() > 0, Item::getPrice, filtersDTO.getMinPrice())
//                .le(filtersDTO.getMaxPrice() > 0, Item::getPrice, filtersDTO.getMaxPrice());
//

//        if (StringUtils.isNotBlank(filtersDTO.getSortBy())) {
//            if ("price".equalsIgnoreCase(filtersDTO.getSortBy())) {
//                wrapper.orderByAsc(Item::getPrice);
//            } else if ("sold".equalsIgnoreCase(filtersDTO.getSortBy())) {
//                wrapper.orderByDesc(Item::getSold);
//            }
//        }

//        PageHelper.startPage(filtersDTO.getPage(), filtersDTO.getSize());
//        if (filtersDTO.getMinPrice() != null && filtersDTO.getMaxPrice() != null) {
//            filtersDTO.setMinPrice(filtersDTO.getMinPrice() * 100);
//            filtersDTO.setMaxPrice(filtersDTO.getMaxPrice() * 100);
//        }
//        Page<Item> page = itemMapper.page(filtersDTO);
//
//        return PageDTO.<Item>builder()
//                .total(page.getTotal())
//                .list(page.getResult())
//                .build();
//    }
//        // 构建分页对象
//        Page<Item> pageRequest = new Page<>(filtersDTO.getPage(), filtersDTO.getSize());
//
//        // 执行分页查询
//        itemMapper.selectPage(pageRequest, null);
//        PageDTO itemPageDTO = new PageDTO();
//        itemPageDTO.setList(pageRequest.getRecords());
//        itemPageDTO.setTotal(pageRequest.getTotal());
//        return itemPageDTO;
//    }

        SearchRequest request = new SearchRequest("items");

        // 1.构建BooleanQuery
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();


        if (StringUtils.isEmpty(filtersDTO.getKey())) {
            boolQuery.must(QueryBuilders.matchAllQuery());
        } else {
            boolQuery.must(QueryBuilders.matchQuery("all", filtersDTO.getKey()));

        }

        // .种类条件
        if (filtersDTO.getCategory() != null && !filtersDTO.getCategory().equals("")) {
            boolQuery.filter(QueryBuilders.termQuery("category", filtersDTO.getCategory()));

        }
        // 4.品牌条件
        if (filtersDTO.getBrand() != null && !filtersDTO.getBrand().equals("")) {
            boolQuery.filter(QueryBuilders.termQuery("brand", filtersDTO.getBrand()));

        }

// 6.价格
        if (filtersDTO.getMinPrice() != null && filtersDTO.getMaxPrice() != null) {
            boolQuery.filter(QueryBuilders
                    .rangeQuery("price")
                    .gte(filtersDTO.getMinPrice())
                    .lte(filtersDTO.getMaxPrice())
            );
        }

        // 7.放入source
        request.source().query(boolQuery);

        //request.source().sort(filtersDTO.getSortBy(),SortOrder.ASC);

        //根据排序
        if (Objects.equals(filtersDTO.getSortBy(), "sold")){
           request.source().sort("sold", SortOrder.ASC);

        }else if (Objects.equals(filtersDTO.getSortBy(), "price") || Objects.equals(filtersDTO.getSortBy(), "default")){
          request.source().sort("price",SortOrder.ASC);
        }


        //分页
        int start = (filtersDTO.getPage()-1) * filtersDTO.getSize();
        //filtersDTO.getSize()
           request.source().from(start).size(filtersDTO.getSize());



        try {
            SearchResponse response = client.search(request, RequestOptions.DEFAULT);
            SearchHits searchHits = response.getHits();
            long total = searchHits.getTotalHits().value;

            SearchHit[] hits = searchHits.getHits();
            List<Item> list = new ArrayList<>();
            for (SearchHit hit : hits) {

                String json = hit.getSourceAsString();

                ItemDoc itemDoc = JSON.parseObject(json, ItemDoc.class);
                Item item = BeanUtil.toBean(itemDoc, Item.class);
                list.add(item);
            }

            PageDTO pageDTO = new PageDTO<>();
            pageDTO.setList(list);
            pageDTO.setTotal(total);

            return pageDTO;

        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void stock(Long itemId, Integer num) {
        Item item = itemMapper.selectById(itemId);
        Integer stock = item.getStock();
        item.setStock(stock-num);
        itemMapper.insert(item);
    }

    @Override
    public List<String> getCategoryList() {
        List<String> category = itemMapper.getCategory();
        List<String> collect = category.stream().distinct().collect(Collectors.toList());

        return collect;
    }

    @Override
    public List<String> getBrandList() {
        List<String> category = itemMapper.getBrand();
        List<String> collect = category.stream().distinct().collect(Collectors.toList());

        return collect;
    }
}
